//
// config.js
// vue3-element-admin
//
// Created by 区区电脑 on 2023/04/10.
//
import LocalDB from "@/utils/LocalDB"
import * as api from "./api.js"
import {defineAsyncComponent} from "vue";
import md5 from "js-md5";
import store from "@/store";
import UserModel from "@/models/UserModel";
import MenuModel from "@/models/MenuModel";

// 白名单
const whiteList = [
    "/workbenches",
    "/ProgramManage/Program/Details",
    "/DeviceManage/Computer/Details",
    "/chinese-getter",
]

// 业务页面文件
const businessPages = {
    ...import.meta.glob("@business/*/*/*/*.vue"),
    ...import.meta.glob("@business/*/*/*.vue"),
    ...import.meta.glob("@business/*/*.vue"),
    ...import.meta.glob("@business/*.vue"),
}

// 是否已经创建了业务页面文件
export function hasPage(route) {
    const page = route.query.page;
    // 不是框架内页面
    if (!page) return true;
    // 框架内页面进行判断是否有文件
    if (businessPages["/business" + route.query.page + ".vue"]) {
        return true;
    }
    console.danger("没有页面文件：", page)
    return false;
}

// 校验是否有 token
export function hasToken() {
    return new Promise(resolve => {
        const token = LocalDB.getItem("token");
        if (token.data) {
            return resolve(true);
        }
        return resolve(false);
    });
}

/**
 * 是否已经登录
 * @returns {Promise<unknown>}
 */
export function hasLogin() {
    return new Promise(async (resolve) => {
        if (!(await hasToken())) return resolve(false);
        // 先查用户信息, 然后查菜单
        const res = await api.GetCurrentUserInfo();
        const userInfo = new UserModel(res.data || {});
        // 赋值用户信息
        // console.log("映射到前端用户信息: ", userInfo);
        store.dispatch("userInfo", userInfo);
        resolve(true)
    })
}

// 是否白名单
export function inWhiteList(path) {
    return whiteList.indexOf(path) > -1;
}

// 是否有权限
export function hasPagePermission(route, next) {
    return new Promise(async resolve => {
        const page = route.query.page;

        const {$message} = window;

        // 侧边栏菜单
        let sideMenus = store.getters.sideMenus;
        // 页面权限
        let pagePermission = store.getters.pagePermission;
        // 页面权限路径集合
        let pagePathPermission = store.getters.pagePathPermission;
        // 按钮权限
        let buttonPermission = store.getters.buttonPermission;
        // 角色权限
        let rolePermission = store.getters.rolePermission;
        let userInfo = store.getters.userInfo;

        // 没有菜单先查询全部授权菜单
        if (sideMenus.length === 0) {
            // 如果是没有侧边栏菜单重新查
            // 先查用户信息, 然后查菜单
            const res = await api.GetCurrentUserInfo();
            userInfo = new UserModel(res.data || {});
            // 赋值用户信息
            store.dispatch("userInfo", userInfo);

            const {success, data = []} = await api.GetLoginMenuList();
            if (!success) return resolve(false);
            // 解析菜单信息为前端菜单数据源
            const {array, tree} = MenuModel.Mapping(data);
            // 全部菜单
            store.dispatch("allMenus", array)
            // console.log("映射到前端菜单信息: ", tree);
            const menuTree = tree.filter(item => item.pId === 0)
            store.dispatch("sideMenus", menuTree)
            sideMenus = tree;

            // 解析页面权限, 并给 pagePermission 赋值
            pagePathPermission = array.filter(item => item.type === 1).map(item => item.path);
            pagePermission = array.filter(item => item.type === 1).map(item => item.code);
            store.dispatch("pagePermission", pagePermission);
            store.dispatch("pagePathPermission", pagePathPermission);
            // 解析按钮权限, 并给 buttonPermission 赋值
            buttonPermission = array.filter(item => item.type === 2).map(item => item.code);
            store.dispatch("buttonPermission", buttonPermission);
            // 解析角色权限, 并给 rolePermission 赋值
            rolePermission = userInfo.rules;
            store.dispatch("rolePermission", rolePermission);

        }
        if (pagePermission.length === 0) {
            // 没有查到权限, 提示联系管理员
            $message.warn("当前账号下没有任何权限, 请联系管理员");
            return next("/login");

            // 没有权限，跳转初始化菜单
            // return next("/initMenu");
        }
        /*** 这里必须先判断了有没有侧边栏菜单之后再判断是不是在白名单，必须按照这个顺序判断 ***/
        // 白名单中页面不需要校验页面权限,但必须登录
        if (inWhiteList(page)) return resolve(true);

        // 校验页面权限中是否存在目标页面
        if (pagePathPermission.findIndex(item => item === page) > -1) {
            // console.log("有页面权限: ", page, pagePermission);
            return resolve(true);
        }
        return resolve(false);
    });
}


// 缓存打开的路由
export function registerComponent(route) {
    return new Promise(resolve => {
        // 组件名
        let componentName = route.query.page;
        if (!componentName) return; // 没有page 参数则不是正规页面, 不处理
        componentName = componentName.replace(/\//g, "");
        // 如果是唯一，则拼接 MD5
        if (route.query.only) {
            componentName += md5(decodeURIComponent(route.fullPath));
            if (store.getters.openedPages.findIndex(item => item.componentName === componentName) > -1) return store.dispatch("activePageComponentName", componentName) && resolve(); // 已经存在则不用重新定义
        } else {
            if (store.getters.openedPages.findIndex(item => item.componentName === componentName) > -1) {
                // 缓存到打开的页面对象中
                store.dispatch("openedPages", {
                    componentName,
                    id: componentName,
                    query: route.query,
                    sourceRoute: route
                });
                store.dispatch("activePageComponentName", componentName) && resolve();
                return;
            }
        }


        // 组件路径
        const componentPath = route.query.page;
        let pathModules = componentPath.split("/").filter(item => item);

        // 定义异步组件，没有注册过的才会注册
        if (!store.getters.registerComponent[componentName]) {
            // 通过全局对象注册组件
            if (pathModules.length === 4) {
                window.$app.component(
                    componentName,
                    defineAsyncComponent(() => import(`../../business/${pathModules[0]}/${pathModules[1]}/${pathModules[2]}/${pathModules[3]}.vue`))
                );
            } else if (pathModules.length === 3) {
                window.$app.component(
                    componentName,
                    defineAsyncComponent(() => import(`../../business/${pathModules[0]}/${pathModules[1]}/${pathModules[2]}.vue`))
                );
            } else if (pathModules.length === 2) {
                window.$app.component(
                    componentName,
                    defineAsyncComponent(() => import(`../../business/${pathModules[0]}/${pathModules[1]}.vue`))
                );
            } else if (pathModules.length === 1) {
                window.$app.component(
                    componentName,
                    defineAsyncComponent(() => import(`../../business/${pathModules[0]}.vue`))
                );
            }
        }

        setTimeout(() => {
            // 缓存到打开的页面对象中
            store.dispatch("openedPages", {
                componentName,
                id: componentName,
                query: route.query,
                sourceRoute: route
            });
            // 缓存注册过的组件，下次再遇到同名的组件可以不用重复注册
            store.dispatch("registerComponent", componentName);
        }, 10) // 延迟10毫秒是为了等路由切换完成在显示组件

        // 设置当前的页面组件
        store.dispatch("activePageComponentName", componentName);
        resolve();
    });
}
